/* Copyright (c) 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.orkut.client.api.samples.greetings.client.ui;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
import com.google.orkut.client.api.samples.greetings.client.DataModel;
import com.google.orkut.client.api.samples.greetings.client.GreetingsCallbackWrapper;
import com.google.orkut.client.api.samples.greetings.client.GreetingsMessages;
import com.google.orkut.client.api.samples.greetings.client.DataModel.DataModelUpdateCallback;
import com.google.orkut.client.api.samples.greetings.client.selector.Item;
import com.google.orkut.client.api.samples.greetings.client.selector.ItemSelector;
import com.google.orkut.client.api.samples.greetings.client.selector.SearchBox;
import com.google.orkut.client.api.samples.greetings.client.services.AlbumsServiceAsync;
import com.google.orkut.client.api.samples.greetings.client.services.PhotoInfo;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * A UI widget to select a photo.
 *
 * @author Shishir Birmiwal
 */
public class PhotoSelector extends ItemSelector<PhotoInfo>
implements DataModelUpdateCallback, AsyncCallback<ArrayList<PhotoInfo>>{
  private static final int MAX_PHOTO_NAME_LENGTH = 15;
  private PhotoSelectedCallback cb;
  private final DataModel data;
  private final AlbumsServiceAsync albumsService;
  private final String st;
  private final GreetingsMessages msgs;
  private final Provider<Item> itemsProvider;
  private final GreetingsCallbackWrapper cbWrapper;

  public static interface PhotoSelectedCallback {
    public void photoSelected(PhotoInfo photo);
  }

  @Inject
  public PhotoSelector(
      SearchBox searchBox,
      @Named("postToken") String postToken,
      Provider<Item> itemsProvider,
      DataModel data,
      GreetingsMessages msgs,
      GreetingsCallbackWrapper cbWrapper,
      AlbumsServiceAsync albumsService) {
    super(searchBox);
    this.st = postToken;
    this.itemsProvider = itemsProvider;
    this.data = data;
    this.msgs = msgs;
    this.cbWrapper = cbWrapper;
    this.albumsService = albumsService;
    data.registerCallback(this);
  }

  public void setPhotoSelectedCallback(PhotoSelectedCallback cb) {
    this.cb = cb;
  }

  @Override
  protected Item getItemFor(final PhotoInfo photo) {
    Item item = itemsProvider.get();
    item.setText(UserSelector.getClippedString(photo.title, MAX_PHOTO_NAME_LENGTH));
    item.setIcon(photo.thumbnailUrl);
    item.setTitle(photo.title);
    item.setCallback(new Item.ItemSelectedCallback() {
      @Override
      public void selected(Item item) {
        if (cb != null) {
          cb.photoSelected(photo);
        }
      }
    });
    return item;
  }

  @Override
  public void update(DataModel data, Type type) {
    if (Type.SELECTED_ALBUM.equals(type)) {
      albumsService.getPhotosOf(st, data.selectedAlbum.ownerId,
          data.selectedAlbum.id, cbWrapper.wrap(this));
      return;
    }
    if (!Type.PHOTOS.equals(type)) {
      return;
    }
    ArrayList<PhotoInfo> newPhotos = new ArrayList<PhotoInfo>();
    HashMap<String,HashMap<String,PhotoInfo>> albumPhotosMap =
        data.userAlbumPhotoInfo.get(data.selectedAlbum.ownerId);
    if (albumPhotosMap != null) {
      HashMap<String, PhotoInfo> photosMap = albumPhotosMap.get(data.selectedAlbum.id);
      if (photosMap != null) {
        newPhotos.addAll(photosMap.values());
      }
    }
    updateItems(newPhotos);
  }

  @Override
  public void onFailure(Throwable caught) {
    Window.alert(msgs.errorFetchingPhotos());
  }

  @Override
  public void onSuccess(ArrayList<PhotoInfo> photos) {
    data.addPhotos(photos);
  }
}
